<template>
  <!-- 设备树 -->
  <div
    class="tree-list"
    id="dtree"
    @click="
      topMenuVisible = false;
      contextMenuType = 0;
    "
    @mousedown="(e) => e.preventDefault()"
  >
    <template v-if="isSearch">
      <!-- <tree-search-header :searchLoading="searchLoading" @search="searchSubmit" @clear="closeSearch"></tree-search-header> -->
    </template>
    <div
      :class="['search-result-content', { 'check-content': isCheckBox }]"
      v-if="searchMode === 1"
    >
      <div class="result-content">
        <div class="result-title">自定义监控目录</div>
        <search-tree-com-cus
          class="tree-com"
          ref="searchTreeComCus"
          :siderEl="siderEl"
          :searchText="searchText"
          :cardInfo="cardInfo"
          :searchType="searchType"
          :isCheckBox="isCheckBox"
          :checkedKeys="checkedKeysCusSearch"
          @check="onCheckCusResult"
          @select="onSelect"
          @playCloudMedia="$emit('playCloudMedia')"
          @refreshGroups="$emit('refreshGroups')"
        ></search-tree-com-cus>
        <div class="result-title">固定监控目录</div>
        <search-tree-com
          class="tree-com"
          ref="searchTreeCom"
          :siderEl="siderEl"
          :searchText="searchText"
          :cardInfo="cardInfo"
          :searchType="searchType"
          :isCheckBox="isCheckBox"
          :checkedKeys="checkedKeysSearch"
          @check="onCheckResult"
          @select="onSelect"
          @playCloudMedia="$emit('playCloudMedia')"
          @refreshGroups="$emit('refreshGroups')"
        ></search-tree-com>
      </div>
    </div>
    <dpro-tree
      class="my-tree"
      v-if="showTree && searchMode === 0"
      :tree-data="treeData"
      :selectedKeys="selectedKeys"
      :expandedKeys="expandedKeys"
      :loadedKeys="loadedKeys"
      showIcon
      :checkable="isCheckBox"
      :checkedKeys="checkedKeys"
      @select="onSelect"
      @expand="onExpand"
      @check="onCheck"
    >
      <!-- @rightClick="rightClick" -->
      <img
        class="custom-sw-icon icon-fold"
        src="./assets/iCON_flod.png"
        slot="switcherIcon"
      />
      <template slot="titleIcon">
        <!-- <span class="icon-sprite icon-iCON_location_online_normal"></span> -->
        <img
          class="icon-location"
          src="./assets/iCON_location_online_normal.png"
        />
      </template>
      <template slot="title" slot-scope="dataRef">
        <template v-if="dataRef.deviceCode">
          <div v-if="dataRef.key" class="item-check">
            <img
              class="icon-device"
              :src="require('./assets/iCON_Divers_online_normal-nocloud.png')"
            />
            <p :id="dataRef.key" class="menu-title">
              {{ dataRef.title
              }}{{ dataRef.deviceCode ? "" : ` (${dataRef.deviceCount || 0})` }}
            </p>
          </div>
          <div v-else>
            <div class="menu-no-title" @click="loadMore(dataRef)">
              {{ dataRef.title }}
            </div>
          </div>
        </template>
        <template v-else>
          <p
            :id="dataRef.key"
            class="menu-title"
            @dblclick="dbclickNode(dataRef)"
          >
            {{ dataRef.title
            }}{{ dataRef.deviceCode ? "" : ` (${dataRef.deviceCount || 0})` }}
          </p>
        </template>
      </template>
    </dpro-tree>
    <div class="tree-empty" v-if="treeData.length === 0">
      <!-- && !loading.getDeviceTreeLoading" -->
      <div class="text">暂无设备</div>
    </div>
  </div>
</template>

<script>
import { flatten } from "../../utils/util";
import deviceTreeMixin from "./device-tree-mixin";
import { DproTree } from "../../components/index";
import TreeSearchHeader from "./tree-search-header.vue";
import SearchTreeCom from './search-tree-com.vue';
import SearchTreeComCus from "./search-tree-com-cus.vue";

export default {
  name: "CascadeTreeCom",
  // treeType:AI能力类型，1-人脸抓拍，2-人脸布控，3-车辆抓拍，6-车辆布控，4-区域告警，5-云广播
  props: [
    "siderEl",
    "treeType",
    "isCheckBox",
    "isSearch",
    "cardInfo",
    "isLive",
    "checkDisableFn",
  ],
  data() {
    return {
      showTree: true,
      contextMenuType: 0, // 右键菜单类型，0不显示，1显示区域菜单，2显示设备菜单
      rightClickItem: null, // 右键菜单
      checkedKeys: [],
      checkedKeysCusSearch: [],
      checkedKeysSearch: [],
      selectedKeys: [],
      topMenuVisible: false,
      searchLoading: false,
      // 是否在搜索中
      searchMode: 0, // 是否搜索模式，0否，1是，搜索模式下展示搜索结果

      searchText: '',
      searchType: '', // 搜索类型，'1'目录，'2'设备名，'3'设备吗
    };
  },
  mixins: [deviceTreeMixin],
  components: {
    DproTree,
    TreeSearchHeader,
    SearchTreeCom,
    SearchTreeComCus,
  },
  computed: {
    // 对应的AI功能相关选项
    // aiItem() {
    //   return AI_OPTIONS.find((item) => item.aiType === this.treeType);
    // },
    reginMenus() {
      return [
        {
          title: "刷新组织树",
          key: "regin-menu-1",
          hidden: false,
        },
        {
          title: "刷新当前节点",
          key: "regin-menu-2",
          hidden: false,
        },
      ];
    },
    deviceMenus() {
      return [
        {
          title: "刷新组织树",
          key: "device-menu-1",
          hidden: false,
        },
        {
          title: "获取设备信息",
          key: "device-menu-3",
          hidden: false,
        },
      ];
    },
    loadedKeys() {
      return flatten(this.treeData)
        .map((item) => {
          return item.children ? item.key : "";
        })
        .filter((key) => key);
    },
    // 当前已请求的所有设备
    flattenDeviceList() {
      return flatten(this.treeData).filter((item) => item.deviceCode);
    },
    flattenTree() {
      return flatten(this.treeData);
    },
  },
  mounted() {
    if (!this.treeData || this.treeData.length === 0) {
      this.getTreeData({ isCheckBox: this.isCheckBox });
      // console.log('tree组件请求根数据');
    }
  },
  methods: {
    searchSubmit(searchText, searchType) {
      console.log("搜索1:", searchText, searchType);
      if (searchText) {
        this.searchMode = 1;
        this.searchText = searchText;
        this.searchType = searchType;
        this.searchLoading = true;
        this.$nextTick(() => {
          this.$refs.searchTreeComCus
            .search()
            .then(() => {
              this.searchLoading = false;
            })
            .catch((err) => {
              this.searchLoading = false;
            });
          this.$refs.searchTreeCom
            .search()
            .then(() => {
              this.searchLoading = false;
            })
            .catch((err) => {
              this.searchLoading = false;
            });
        });
      } else {
        // 未输入内容点击搜索时退出搜索
        this.closeSearch();
      }
    },
    closeSearch() {
      this.searchMode = 0;
    },
    // 展开设备树某个列表
    onLoadData(treeNode) {
      // console.log('onLoadData')
      return new Promise((resolve) => {
        if (treeNode.dataRef.children) {
          // console.log('children已存在')
          resolve();
          return;
        }
        let params = {
          parentId: treeNode.dataRef.id,
          parentRegionCode: treeNode.dataRef.regionCode,
          treeType: treeNode.dataRef.treeType,
          isGetDeviceList: treeNode.dataRef.havDevice === 1,
          hasChildren: treeNode.dataRef.hasChildren,
          isCheckBox: this.isCheckBox,
        };
        this.getTreeData(params).finally(() => {
          resolve();
        });
      });
    },
    // 加载更多
    loadMore(dataRef) {
      return new Promise((resolve) => {
        let params = {
          parentId: dataRef.pid,
          treeType: dataRef.treeType,
          isGetDeviceList: true,
          hasChildren: false,
          isMoreDevice: true,
          preDevice: dataRef.preDevice,
          prePageNo: dataRef.prePageNo + 1,
          isCheckBox: this.isCheckBox,
        };
        this.getTreeData(params).finally(() => {
          // 如果父节点被选中，则新加载出来的设备也应被选中
          if (this.checkedKeys.includes(dataRef.pid)) {
            let devices =
              this.flattenTree.find((it) => it.key === dataRef.pid)?.children ||
              [];
            devices.forEach((it) => {
              // 因异步加载遗漏的选中设备未被勾选
              if (!this.checkedKeys.includes(it.deviceCode)) {
                this.checkedKeys.push(it.deviceCode);
              }
              let nodes = this.flattenTree.filter(
                (item) =>
                  Array.isArray(item.children) &&
                  item.children.find((d) => d.deviceCode === it.deviceCode)
              );
              nodes.forEach((node) => {
                if (
                  !this.checkedKeys.includes(node.key) &&
                  node.children.every((child) =>
                    this.checkedKeys.includes(child.deviceCode)
                  )
                ) {
                  this.checkedKeys.push(node.key);
                }
              });
            });
            let checkedDevices = this.checkedKeys
              .map((it) =>
                this.flattenDeviceList.find((item) => item.deviceCode === it)
              )
              .filter((it) => it);
            this.$emit("check", checkedDevices);
          }
          resolve();
        });
      });
    },
    async onCheckResult(checkedKeys, flattenDeviceList, event) {
      this.checkedKeysSearch = [...checkedKeys];

      let checkedDevices = checkedKeys
        .map((it) => flattenDeviceList.find((item) => item.deviceCode === it))
        .filter((it) => it);
      this.$emit("check", checkedDevices);
    },
    async onCheckCusResult(checkedKeys, flattenDeviceList, event) {
      this.checkedKeysCusSearch = [...checkedKeys];

      let checkedDevices = checkedKeys
        .map((it) => flattenDeviceList.find((item) => item.deviceCode === it))
        .filter((it) => it);
      this.$emit("check", checkedDevices);
    },
    // 选择视频设备
    async onCheck(checkedKeys, event) {
      const { dataRef } = event.node;
      console.log(
        "-----oncheck---",
        checkedKeys,
        dataRef.key,
        event.checked,
        event
      );
      // 若未展开该节点，则自动展开
      if (
        dataRef &&
        !dataRef.deviceCode &&
        !this.expandedKeys.includes(dataRef.key)
      ) {
        await this.onExpand([...this.expandedKeys, dataRef.key]);
        await this.onLoadData(event.node);
      }

      let checkedNodes = checkedKeys.map((it) =>
        this.flattenTree.find((item) => item.key === it)
      );

      if (dataRef.deviceCode) {
        // 包含该设备的所有目录节点
        let nodes = this.flattenTree.filter(
          (it) =>
            Array.isArray(it.children) &&
            it.children.find((item) => item.deviceCode === dataRef.deviceCode)
        );
        if (event.checked) {
          // 检查是否需要增加上一层节点选中
          nodes.forEach((it) => {
            if (
              !checkedKeys.includes(it.key) &&
              it.children.every((item) => checkedKeys.includes(item.key))
            ) {
              checkedKeys.push(it.key);
            }
          });
        } else {
          // 检查是否需要取消勾选上一层节点
          nodes.forEach((it) => {
            checkedKeys = checkedKeys.filter((k) => k !== it.key);
          });
        }
      } else {
        // 操作目录节点，勾选/取消勾选节点下所有设备，并检查其他目录节点勾选情况
        let devices =
          this.flattenTree.find((it) => it.key === dataRef.key)?.children || [];
        if (event.checked) {
          // 检查所有相关设备所在目录的勾选情况，如果发现某目录下所有设备均被勾选，则勾选该目录
          devices.forEach((it) => {
            // 因异步加载遗漏的选中设备未被勾选
            if (!checkedKeys.includes(it.deviceCode)) {
              checkedKeys.push(it.deviceCode);
            }
            let nodes = this.flattenTree.filter(
              (item) =>
                Array.isArray(item.children) &&
                item.children.find((d) => d.deviceCode === it.deviceCode)
            );
            nodes.forEach((node) => {
              if (
                !checkedKeys.includes(node.key) &&
                node.children.every((child) =>
                  checkedKeys.includes(child.deviceCode)
                )
              ) {
                checkedKeys.push(node.key);
              }
            });
          });
        } else {
          // 取消勾选该节点下所有设备
          devices.forEach((it) => {
            checkedKeys = checkedKeys.filter((k) => k !== it.key);
          });
          // 检查所有相关设备所在目录的勾选情况，如果发现某目录下存在设备未勾选，则取消勾选该目录
          checkedNodes.forEach((it) => {
            if (
              !it.deviceCode &&
              it.children.some(
                (item) =>
                  !!devices.find((d) => d.deviceCode === item.deviceCode)
              )
            ) {
              checkedKeys = checkedKeys.filter((k) => k !== it.key);
              // console.log('同步取消勾选目录', it.title, it.key);
            }
          });
        }
      }
      this.checkedKeys = [...checkedKeys];
      console.log("-----oncheck-2--", this.checkedKeys);

      this.selectedKeys = [dataRef.key]; // 不允许点击两次取消选择

      let checkedDevices = checkedKeys
        .map((it) =>
          this.flattenDeviceList.find((item) => item.deviceCode === it)
        )
        .filter((it) => it);
      this.$emit("check", checkedDevices);
    },
    // 选择视频设备
    onSelect(selectedKeys, event) {
      // console.log('onSelect',event.node.dataRef);
      this.contextMenuType = 0;
      this.selectedKeys = [event.node.dataRef.key]; // 不允许点击两次取消选择
      // if (event.node.dataRef && event.node.dataRef.deviceCode) {
      //   // 选择了摄像头设备
      //   let deviceInfo = event.node.dataRef;
      //   this.setSelectedDevice(deviceInfo); // 存储选择状态
      // }
      this.$emit("select", event.node.dataRef);
    },
    // 双击
    dbclickNode(dataRef) {
      this.$emit("dbClick", dataRef);
      if (!dataRef.deviceCode) {
        // 展开/收起节点
        this.switchExpand(dataRef.key);
      }
    },

    // 右击
    rightClick({ event, node }) {
      this.contextMenuType = 0;
      this.$nextTick(() => {
        this.topMenuVisible = false;
        event.stopPropagation();
        this.rightClickItem = node.dataRef;
        if (node.dataRef.id) {
          // 显示区域菜单
          this.contextMenuType = 1;
          this.selectedKeys = [node.dataRef.key];
          this.$emit("select", node.dataRef);
        } else if (node.dataRef.deviceCode) {
          // 显示设备菜单
          this.contextMenuType = 2;
          this.selectedKeys = [node.dataRef.key];
          this.$emit("select", node.dataRef);
          // this.setSelectedDevice(node.dataRef);
        } else {
          this.contextMenuType = 0;
        }
      });
    },

    // 点击分组菜单选项
    clickReginMenu({ key }) {
      let { id } = this.rightClickItem || {};
      if (id) {
        switch (key) {
          case "regin-menu-1":
            // 刷新组织树
            this.refreshTree();
            break;
          case "regin-menu-2":
            // 刷新当前节点
            this.refreshCurrentRegin();
            break;
        }
      }
    },

    // 点击设备菜单选项
    clickDeviceMenu({ key }) {
      let { deviceCode } = this.rightClickItem || {};
      if (deviceCode) {
        switch (key) {
          case "device-menu-1":
            // 刷新组织树
            this.refreshTree();
            break;
          case "device-menu-3":
            // 获取设备信息
            this.showDeviceInfo();
            break;
        }
      }
    },
    // 刷新当前节点
    refreshCurrentRegin() {
      if (!this.rightClickItem) return;
      let reginItem = this.rightClickItem;
      // 关闭该节点下已展开的节点
      this.collspandRelativeKeys(reginItem.key);

      let params = {
        parentId: reginItem.id,
        parentRegionCode: reginItem.regionCode,
        treeType: reginItem.treeType,
        isGetDeviceList: reginItem.havDevice === 1,
        hasChildren: reginItem.hasChildren,
        showLoading: true,
        refreshNode: true,
        isCheckBox: this.isCheckBox,
      };
      this.getTreeData(params);
    },
    // 关闭某节点下已展开的节点
    collspandRelativeKeys(key) {
      let exKeyPaths = [];
      // console.log('expandedKeys:',this.expandedKeys)
      this.expandedKeys.forEach((exKey) => {
        let res = this.getItemByKey(exKey, this.treeData);
        res && exKeyPaths.push(res.keyPath);
      });
      // console.log('exKeyPaths:',exKeyPaths)
      exKeyPaths.forEach((item) => {
        let arr = item.split("/");
        arr && arr.length > 0 && arr.pop();
        if (arr.includes(String(key))) {
          // 删除key下已展开的子节点
          let deleteKey = item.substring(item.lastIndexOf("/") + 1);
          // console.log('expandedKeys-deleteKey:',deleteKey);
          this.expandedKeys.forEach((item, index) => {
            if (item === deleteKey) this.expandedKeys.splice(index, 1);
          });
        }
      });
      // console.log('af-expandedKeys:',this.expandedKeys)
    },
    // 根据key获取item
    getItemByKey(key, tree) {
      let item = tree.find((item) => item.key === key);
      if (!item) {
        // 查找深层子节点
        for (let i = 0, len = tree.length; i < len; i++) {
          let itm = tree[i];
          if (itm.children && itm.children.length > 0) {
            item = this.getItemByKey(key, itm.children);
            if (item) break;
          }
        }
      }
      // item && console.log(`${key}的keyPath：${item.keyPath}`)
      return item;
    },
    // 刷新分组数组
    async refreshTree() {
      // this.$emit('refreshTree');
      this.selectedKeys = [];
      this.expandedKeys = [];
      this.checkedKeysCusSearch= [];
      this.checkedKeysSearch= [];
      // this.loadedKeys = [];
      this.showTree = false;
      await this.$nextTick();
      this.showTree = true;
      this.getTreeData({ isCheckBox: this.isCheckBox });
    },

    // 查询设备信息
    showDeviceInfo() {
      this.$refs.deviceInfoModal.open({
        data: {
          deviceCode: this.rightClickItem?.deviceCode,
          deviceName: this.rightClickItem?.deviceName,
          pathName: this.rightClickItem?.pathName,
        },
        updateCallback: (info) => {},
      });
    },

    // 展开节点
    addToExpand(keys = []) {
      keys.forEach((key) => {
        if (!this.expandedKeys.includes(key)) {
          this.expandedKeys.push(key);
        }
      });
    },
  },
};
</script>

<style lang="less" scoped>
@import "../../components/tree/src/tree/index.less";

.tree-list {
  position: relative;
  min-height: 1;
  flex: 1;
  overflow: hidden;

  // 搜索
  .search-result-content {
    overflow: auto;
    height: 89%;
    &::-webkit-scrollbar{
      display: none;
    }
    &.check-content {
      height: 100%;
    }
    .result-title {
      flex: 0 0 auto;
      padding-left: 12px;
      opacity: 0.6;
    }
    .result-content {
      height: 100%;
    }
  }

  .my-tree {
    position: relative;
    height: 100%;
    overflow: auto;
    color: white;

    &::-webkit-scrollbar {
      display: none;
    }

    .menu-title {
      margin: 0;
      display: inline-block;
      // min-width: 160px;
      line-height: 32px;
      user-select: none;
    }

    .custom-sw-icon {
      margin: 3px;
    }

    /deep/ .anticon-loading {
      margin: 3px;
    }

    /deep/ .ant-tree-node-content-wrapper {
      display: initial;
      padding: 0;
      line-height: 36px;

      &:hover {
        background-color: transparent;
      }

      .ant-tree li span.ant-tree-switcher,
      .ant-tree li span.ant-tree-iconEle {
        line-height: inherit;
      }
    }

    /deep/ .ant-tree-child-tree {
      padding-left: 36px;
    }

    /deep/ li {
      padding: 0 0 0 3px;
      white-space: nowrap;
    }

    /deep/ li span.ant-tree-switcher.ant-tree-switcher-noop {
      display: none;
    }

    /deep/ .ant-tree-switcher {
      display: inline-flex;
      align-items: center;
      justify-content: center;
      width: 24px;
      height: 24px;
      vertical-align: unset;
      transition: transform 0.167s;
      transform: rotate(-90deg);
    }

    /deep/ .ant-tree-iconEle {
      width: 24px;
      height: 24px;
      margin-right: 2px;
      vertical-align: baseline;
    }

    /deep/ .ant-tree-iconEle:empty {
      display: none;
    }

    /deep/ .menu-no-title {
      cursor: pointer;
    }

    /deep/ .ant-tree-switcher_open {
      transform: rotate(0deg);

      .loading {
        display: inline-block;
        width: 12px;
        height: 12px;
        border-color: #fff;
        border-top-color: transparent;
      }
    }
  }

  .tree-com {
    /deep/ .menu-title {
      margin: 0;
    }
    /deep/ .ant-tree li .ant-tree-node-content-wrapper:hover {
      background: transparent;
    }
  }

  .tree-loading {
    position: absolute;
    left: 50%;
    top: 50%;
    transform: translate3d(-50%, -50%, 0);
  }

  .context-block {
    position: absolute;
    width: 100%;
    height: 100%;
  }

  .tree-empty {
    position: absolute;
    top: 60%;
    left: 50%;
    width: 100%;
    transform: translate3d(-50%, -50%, 0);
    text-align: center;

    .img-empty {
      width: 58px;
      height: 58px;
    }

    .text {
      // margin-top: 6px;
      font-size: 12px;
      opacity: 0.6;
    }

    button {
      width: 120px;
      margin-top: 16px;
    }
  }
}

.icon-location {
  width: 24px;
  height: 24px;
  transform: translateY(-10%);
}

.icon-device {
  width: 25px;
  height: 25px;
  margin-right: 2px;
}

.icon-fold {
  width: 14px;
  height: 14px;
  margin-bottom: 2px;
}

.item-check {
  display: inline-block;
}
</style>
